#include <windows.h>
#include "dxManager.h"
#include <dinput.h>
#include <dxerr9.h>
#include <dsound.h>
#include "dsutil.h"
#include "keyboard.h"
#include "game.h"

// camera variables
D3DXMATRIX matView;					// the view matrix
D3DXMATRIX matProj;					// the projection matrix
D3DXVECTOR3 cameraPosition;			// the position of the camera
D3DXVECTOR3 cameraLook;				// where the camera is pointing

Game game;
bool initWindow(HINSTANCE hInstance);
bool initDirect3D(HWND hwnd);
void createCamera(float nearClip, float farClip);
void moveCamera(D3DXVECTOR3 vec);
void pointCamera(D3DXVECTOR3 vec);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	initWindow(hInstance);
	game.hInst = &hInstance;
	initDirect3D(game.wndHandle);
	game.Init(&matView); 

	createCamera(1.0f, 500.0f);		// near clip plane, far clip plane
	moveCamera(D3DXVECTOR3(0.0f, 0.0f, 0.0f));
	//pointCamera(D3DXVECTOR3(0.0f, 0.0f, 0.0f));

	MSG msg; 
    ZeroMemory( &msg, sizeof(msg) );
    while( msg.message!=WM_QUIT )
    {
		if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
		{
			TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
		else
		{
			game.Update();
			game.Draw();
		}
    }

	game.shutDown();
	 
	return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}

bool initWindow(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= 0;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= "Super Rave RPG XIV Turbo";
	wcex.hIconSm		= 0;
	RegisterClassEx(&wcex);

	game.wndHandle = CreateWindow("Super Rave RPG XIV Turbo", 
							 "Super Rave RPG XIV Turbo", 
							 WS_OVERLAPPEDWINDOW,
							 CW_USEDEFAULT, 
							 CW_USEDEFAULT, 
							 SCREEN_WIDTH, 
							 SCREEN_HEIGHT, 
							 NULL, 
							 NULL, 
							 hInstance, 
							 NULL);
   if (!game.wndHandle)
      return false;
   
   ShowWindow(game.wndHandle, SW_SHOW);
   UpdateWindow(game.wndHandle);

   return true;
}

bool initDirect3D(HWND hwnd)
{
	HRESULT hr;

	if( NULL == ( game.pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
	{
		return false;
	}

	D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.BackBufferCount  = 1;
	d3dpp.BackBufferHeight = 640;
	d3dpp.BackBufferWidth  = 640;
	d3dpp.hDeviceWindow    = hwnd;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    hr = game.pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
                             D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                             &d3dpp, &game.pd3dDevice );
	if FAILED (hr)
    {
        return false;
    }

	// set the default render states
	game.pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
	game.pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
	game.pd3dDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
	game.pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(0, 0, 0));
	game.pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);	
	game.pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

	return true;
}

void createCamera(float nearClip, float farClip)
{
	//Here we specify the field of view, aspect ration and near and far clipping planes.
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, SCREEN_HEIGHT/SCREEN_WIDTH, nearClip, farClip);
    game.pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}

void moveCamera(D3DXVECTOR3 vec)
{
	cameraPosition = vec;
}

void pointCamera(D3DXVECTOR3 vec)
{
	cameraLook = vec;

	D3DXMatrixLookAtLH(&matView, &cameraPosition,		//Camera Position
                                 &cameraLook,			//Look At Position
                                 &D3DXVECTOR3(0.0f, 1.0f, 0.0f));		//Up Direction

	game.pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
}